
/* ->c.mym */

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <time.h>

#include "h.os"
#include "h.wimp"



#include "h.def"

#include "h.wos"
#include "h.main"
#include "h.ram"
#include "h.file"

#include "h.cross"
#include "h.dc"
#include "h.sp"

#include "h.mym"



/*****************************************************************************/

int menublock[0x201];    /* char 0x804 */


int * menus[160];
int * lastmenu;
int * slastmenu;

int   repopf;


static int  oldmx,oldmy;
static int  * oldmenu;



void load_menus()
{
 int  * base;   
 FILE * fp;
 int    load;
 int    numenus;
 int    menuc;
 int    flags;
 int    subs;
 int    iflag;
 int    idat1;


 base=(int *)menublock;

 fp=fopen("<CrossStar$Path>.resources.menu","rb");

 fread(&load,sizeof(int),1,fp);

 numenus=getc(fp);

 for(menuc=0;menuc<numenus;menuc++)
 {
  menus[menuc]=base;
  fread(base,sizeof(int),7,fp);
  base+=7;

  do
  {
   fread(base,sizeof(int),1,fp);
   flags=*base;
   base++;

   fread(&subs,sizeof(int),1,fp);
   if(subs>0) subs=subs-load+(int)menublock;
   *base=subs;
   base++;

   fread(base,sizeof(int),1,fp);
   iflag=*base;
   base++;

   fread(&idat1,sizeof(int),1,fp);
   if(iflag & 0x100) idat1=idat1-load+(int)menublock;
   *base=idat1;
   base++;

   fread(base,sizeof(int),2,fp);
   base+=2;

  } while((flags & 0x80)==0);
 }

 fread(base,1,sizeof(menublock)-(base-menublock)*sizeof(int),fp);

 fclose(fp);
 slastmenu=lastmenu=NULL;
}                   


void mwpoint(menuhandle,item,pointer) int * menuhandle; int item,pointer;
{
 *(menuhandle+(7+1+6*item))=pointer;
}


/* return a pointer to a menu's sub menu */

int * pointm(int * menuhandle,int item)
{
 return((int *)(*(menuhandle+(7+1+6*item))));
}



void shade(menuhandle,item)  int * menuhandle; int item;
{
 *(menuhandle+(7+2+6*item))=*(menuhandle+(7+2+6*item)) | 0x400000;
}




void dynamic(menuhandle,item)  int * menuhandle; int item;
{
 *(menuhandle+(7+6*item))=*(menuhandle+(7+6*item)) | 0x8;
}


void unshade(menuhandle,item)  int * menuhandle; int item;
{
  shade(menuhandle,item);
 *(menuhandle+(7+2+6*item))=*(menuhandle+(7+2+6*item)) ^ 0x400000;
}



void tick(menuhandle,item)  int * menuhandle; int item;
{
 *(menuhandle+(7+6*item))=*(menuhandle+(7+6*item)) | 0x1;
}

void untick(menuhandle,item)  int * menuhandle; int item;
{
  tick(menuhandle,item);
 *(menuhandle+(7+6*item))=*(menuhandle+(7+6*item)) ^ 0x1;
}

void tickst(int * menuhandle,int item,int state)
{
 if(state) tick(menuhandle,item);
 else      untick(menuhandle,item);
}

void untickmenu(int * menuhandle)
{
 int item=0;

 while(menuhandle)
 {
  *(menuhandle+(7+6*item))&=0xFFFFFFFE;
  if((*(menuhandle+(7+6*item))) & 0x80) break;
  item++;
 }
}




/*

void undynamic(menuhandle,item)  int * menuhandle; int item;
{
  dynamic(menuhandle,item);
 *(menuhandle+(7+6*item))=*(menuhandle+(7+6*item)) ^ 0x8;
}

 */


void unshadest(int * menuhandle,int item,int state)
{
 if(state) unshade(menuhandle,item);
 else      shade(menuhandle,item);
}




char * menuaddr(menuhandle,item) int * menuhandle; int item;
{ int * i;
  i=(menuhandle+(7+6*item));
  if( (* (i+2)) & 0x100) return((char *)(*(i+3)));
  else                   return((char *)(i+3));
}


void writemenu(int * menuhandle,int item,char * string)
{
 int  * i;
 char * p;
 int    j;

 i=(menuhandle+(7+6*item));
 if( (* (i+2)) & 0x100) p=(char *)(*(i+3));
 else                   p=(char *)(i+3);

 for(j=0;j<12;j++)
 {
  if(*string) *p++=*string++;
  else        *p++=32;
 }
}



void writemenuf(int * menuhandle,int item,char * format, ...)
{
 va_list args;
 va_start(args, format);
 vsprintf(menuaddr(menuhandle,item), format, args);
 va_end(args);
}



/* attempt to read an integer from a menu entry */
/* return 1 on success                          */

int getmenuint(int * menuhandle,int item,int * val)
{
 int code;
 code=sscanf(menuaddr(menuhandle,item),"%d",val);
 return(code==1);
}



/*

int * menuicon(int * menuhandle,int item)
{
  return(menuhandle+(7+6*item+2));
}

*/

int islastm(int * menuhandle,int item)
{
 return((*(menuhandle+(7+6*item))) & 0x80);
}



void menumakelastst(int * menuhandle,int item,int state)
{
 if(state) *(menuhandle+(7+6*item))|=0x80;
 else      *(menuhandle+(7+6*item))&=0x7F;
}



void unshademenust(int * menuhandle,int item,int state)
{
 menuhandle=pointm(menuhandle,item);
 if(menuhandle)
 {
  item=0;
  while(1)
  {
   unshadest(menuhandle,item,state);
   if(islastm(menuhandle,item)) break;
   item++;
  }
 }
}






void popup_menu(menuhandle,x,y) int * menuhandle; int x,y;
{
 os_error * ep;

 ep=wimp_create_menu((wimp_menustr *)menuhandle,x,y);
 if(ep)
 {
  report(ep);
  return;
 }

 oldmenu=menuhandle;
 oldmx=x;
 oldmy=y;

 slastmenu=lastmenu=menuhandle;
}


void popmenu(menuhandle) int * menuhandle; 
{
 wimp_mousestr mstr;
 wimp_get_point_info(&mstr);
 if(menuhandle==info_menu && mstr.y<200) mstr.y=96;
 popup_menu(menuhandle,mstr.x-80,mstr.y+80);
}


void repopmenu(void)
{
 popup_menu(oldmenu,oldmx,oldmy);
}

int repop(void)
{
 wimp_mousestr mstr;
 wimp_get_point_info(&mstr);
 return(mstr.bbits & 0x1);
}

void zapmenu(void)
{
 wimp_create_menu((wimp_menustr *)-1,0,0);
}




/************************************************************************/

void markstring(char * result)
{
 strcpy(result,"2.14 (01-Dec-2011)");
}


void setpopinfo(void)
{

}



void decodeinfo(int m1,int m2,int m3,int m4,int m5)
{    
 switch(m1)
 {
   case 1:
         terminatec();
         break;
 }

 setpopinfo();

 m3=m4=m5;
}



void popinfo(void)
{
 char string[64];
 int  handle;

 handle=createwindow(INFO);
 if(!handle) return;

 markstring(string);
 writeicon(handle,3,string);
 mwpoint(info_menu,0,handle);

 setpopinfo();

 popmenu(info_menu);
}


void decodeiconbar(void)
{
 if(buttons==2) popinfo();
 else           crossopenup();
}




/*****************************************************************************/



void setpopmain(void)
{
 writemenuf(width_menu,0,"%d",maxx);
 writemenuf(height_menu,0,"%d",maxy);

 tickst(file_menu,4,saveupper);
 tickst(file_menu,5,draftfill);

}




void popmain(void)
{
 setpopmain();
 popmenu(main_menu);
}






void decodewords(int m3,int m4)
{
 if(m4!=-1)
 {
  switch(m3)
  {
    case 1:
           loaddict(m4);
           break;

    case 2:
           editdict(m4);
           break;

    case 3:
           createdict(menuaddr(created_menu,0));
           break;

    case 4:
           deletedict(m4);
           break;
  }
  setdictm(m3-1);
 }
 else
  if(m3==0) spellcheck();
}







void decodereflect(int m3)
{
 switch(m3)
 {
  case 0:
         reflectvert();
         break;

  case 1:
         reflecthoriz();
         break;

  case 2:
         reflectdiag1();
         break;

  case 3:
         reflectdiag2();
         break;
 }
}




void decodegrid(int m2,int m3)
{
 int size;

 switch(m2)
 {

  case 0:
         clear_words();   /* clear */
         break;

  case 1:                 /* new */
         clear_screen();
         break;

  case 2:                 /* width */
         if(getmenuint(width_menu,0,&size))  setsize(size,maxy);
         break;           

  case 3:                 /* height */
         if(getmenuint(height_menu,0,&size)) setsize(maxx,size);
         break;

  case 4:                 /* reflect */
         decodereflect(m3);
         break;


 }
}




void decodemain(int m1,int m2,int m3,int m4,int m5)
{
 switch(m1)
 {
  case 0: /* file */
         if(m2==3) savedefaultgrid();
         else
         if(m2==4) saveupper^=1;
         else
         if(m2==5) draftfill^=1;
         break;

  case 1: /* words */
         decodewords(m2,m3);
         break;

  case 2: /* grid */
         decodegrid(m2,m3);
         break;
 }

 setpopmain();
}







/***************************************************************************/

void setupmenus(void)
{
 load_menus();

 dynamic(word_menu,1);
 dynamic(word_menu,2);
 dynamic(word_menu,4);

 dynamic(file_menu,0);
 dynamic(file_menu,1);
 dynamic(file_menu,2);
}


void decodemen(void)
{
 int menu1,menu2,menu3,menu4,menu5;
 int * lastmenuc;

 menu1=wimpevent.data.menu[0];
 menu2=wimpevent.data.menu[1];
 menu3=wimpevent.data.menu[2];
 menu4=wimpevent.data.menu[3];
 menu5=wimpevent.data.menu[4];

 if(menu1==-1) return;
 lastmenuc=lastmenu;
 slastmenu=lastmenu=NULL;
 repopf=repop();

      if(lastmenuc==main_menu)   decodemain(menu1,menu2,menu3,menu4,menu5);    
 else if(lastmenuc==info_menu)   decodeinfo(menu1,menu2,menu3,menu4,menu5);    

 if(repopf) repopmenu();
}


/* called on dynamic menu event */

void dynamicmenu(int submenu,int x,int y,int m1,int m2,int m3,int m4)
{
 os_error * ep;

 if(lastmenu==main_menu)
 {
  if(m1==0 && m2==0) submenu=setsave(SAVEASGRID);
  else
  if(m1==0 && m2==1) submenu=setsave(SAVEASDRAW);
  else
  if(m1==0 && m2==2) submenu=setsave(SAVECLUES);
  else
  if(m1==1) 
  {
   submenu=(int)setdictm(m2-1);
   mwpoint(word_menu,m2,submenu);
  }
 }

 ep=wimp_create_submenu((wimp_menustr *)submenu,x,y);
 if(ep) report(ep);

 m3=m4=0;
}

